package com.lazy.mongodemo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class DemoInsertMtGps {
    private static final Logger logger = LoggerFactory.getLogger(DemoInsertMtGps.class);

    private MongoClient client;
    private MongoCollection<Document> coll;

    public DemoInsertMtGps(String url){
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();
        // credentials.add(MongoCredential.createCredential("sms_test", "ecodeSms", "sms_test".toCharArray()));
        //client = new MongoClient(new ServerAddress("127.0.0.1", 27017), credentials);
        
        MongoClientURI connectionString = new MongoClientURI(url);
        client = new MongoClient(connectionString);
        // client = new MongoClient(host, port);
 
        // MongoDatabase db = client.getDatabase("mydb");
        MongoDatabase db = client.getDatabase("gwgps");
        coll = db.getCollection("location");
//        coll.drop();
//        coll.dropIndexes();// 先删除所有索引
//        coll.createIndex(new BasicDBObject("hostid",1));
//        coll.createIndex(new BasicDBObject("posTime",1));

    }

    public void testInsert(ExecutorService executorService) {
        long startTime = System.currentTimeMillis();
        //logger.info("startTime  {}  ", startTime);
        
        int batchNum = 100;
        CountDownLatch latch = new CountDownLatch(batchNum);
        for (int i = 0; i < batchNum; i++) {
            executorService.submit(new Worker(this, latch, i));
        }
        
        try{
            latch.await();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        //shutdown() 方法在终止前允许执行以前提交的任务
        //第一阶段调用 shutdown 拒绝传入任务，然后调用 shutdownNow（如有必要）取消所有遗留的任务
        //提交的任务运行结束后关闭线程池
        // executorService.shutdown(); 
        long endTime = System.currentTimeMillis();
        //logger.info("endTime  {}  ", endTime);
        logger.info("insert 10w takes time  {}  ", (endTime - startTime));
    }
    
    private void insertBatch(int batchLimit, int flag) {
        int c = 1;
        List<Document> list = new ArrayList<Document>();
        
        for (int i = 0; i < batchLimit; i++) {
            Document d = GpsDocument.toDoc(flag);
            d.put("_id", new ObjectId((Date)d.get("posTime")));
            d.put("idx", c);
            list.add(d);
        }
        coll.insertMany(list);
    }


    public static void main(String[] args){
        //String host = "192.168.1.234";
        //int port = 37017;
        int count = 10;
        int poolCount = 2;
        // String url = "mongodb://192.168.1.234:37017";
        String url = "mongodb://192.168.1.178:27017";
        if (args.length == 3) {
            url = args[0];
            count = Integer.valueOf(args[1]);
            poolCount = Integer.valueOf(args[2]);
        }
        logger.info("connecting to mongodb {}  group count {} poolCount {}", url, count, poolCount);
        final DemoInsertMtGps demo = new DemoInsertMtGps(url);
        ExecutorService executorService = Executors.newFixedThreadPool(poolCount);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            demo.testInsert(executorService);
        }
        
        executorService.shutdown();
        long endTime = System.currentTimeMillis();
        logger.info("all take time {} ms", (endTime - startTime));
    }
    
    
    static class Worker implements Runnable { 
        CountDownLatch latch;
        DemoInsertMtGps demoInsert;
        int flag;// 做一些特殊的处理, 这里是做参数校验
        
        public Worker(DemoInsertMtGps demoInsert, CountDownLatch latch, int flag){
            this.demoInsert = demoInsert;
            this.latch = latch;
            this.flag = flag;
        }
        
        public void run() { 
            try{
                demoInsert.insertBatch(1000, flag);
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                latch.countDown();
            }

        }
    }

}
